from django.shortcuts import render_to_response
from django.http import HttpResponsePermanentRedirect
from django.core.urlresolvers import reverse

# Models

from django.contrib.auth.models import User
from devnote.app.models import Category, Entity

# Forms

from app.models import AddCategoryForm, \
                       DeleteCategoryForm, \
                       EditCategoryForm, \
                       EditNoteTitleForm, \
                       EditNoteImportanceForm, \
                       EditNotePriorityForm, \
                       EditNoteDescriptionForm, \
                       EditNoteTypeForm, \
                       ArchiveNoteForm, \
                       DeleteNoteForm, \
                       RestoreNoteForm, \
                       AddNoteForm, \
                       AddDataShortForm, \
                       FilterDataShortForm

import re

# TODO: review
# Categories

def add_childs(categories, parent):
    """Add all child categories."""
    
    childs = Category.objects.filter(parent=parent.id)
    had_childs = True
    for ch in childs:
        if had_childs:
            categories.append([])
            had_childs = False
        
        categories[len(categories)-1].append(ch)
        
        if len(Category.objects.filter(parent=ch.id)) != 0:
            add_childs(categories, ch)
            had_childs = True

def get_categories(curr_user):
    """Return all user's categories."""
    
    # all_cat = Category.objects.filter(user=curr_user)
    
    categories = []
    parents = Category.objects.filter(user=curr_user,level=1)
    had_childs = True
    for par in parents:
        if had_childs:
            categories.append([])
            had_childs = False
        
        categories[len(categories)-1].append(par)
        
        if len(Category.objects.filter(parent=par.id)) != 0:
            add_childs(categories, par)
            had_childs = True
    
    return categories

def add_category(title, parent_id, user):
    """Add category."""
    
    # if no parent selected
    if parent_id == 0:
        level = 1
        position = len(Category.objects.filter(level=1)) + 1
        
        category = Category(title=title,level=level,position=position,user=user)
    else:
        parent_lvl = Category.objects.get(id=parent_id).level
        
        level = parent_lvl + 1
        if level > 4:
            return
        
        position = len(Category.objects.filter(parent=parent_id)) + 1
        
        category = Category(parent=parent_id,title=title,level=level,position=position,user=user)
    
    category.save()

def modify_categories(p_id):
    """Modify all child categories."""
    
    parent = Category.objects.get(id=p_id)
    childs = Category.objects.filter(parent=p_id)
    
    if len(childs) != 0:
        for child in childs:
            modify_categories(child.id)
            child.level = parent.level
            child.save()

def delete_category(id):
    """Delete category."""
    
    category = Category.objects.get(id=id)
    
    childs = Category.objects.filter(parent=id)
    if len(childs) != 0:
        for child in childs:
            modify_categories(child.id)
            child.parent = category.parent
            child.level = category.level
            child.save()
    
    category.delete()

# Notes

# TODO: review
def get_notes(curr_user, state):
    """Return user's notes by state."""
    
    all_data = Entity.objects.filter(user=curr_user,type='N',state=state)
    
    return all_data

# Data

def parse_input(in_str):
    """Return dictionary of values parsed by identifiers."""
    
    re_str = r' *\\[ntecipxdrm] '
    
    pos = []
    
    itr = re.finditer(re_str, in_str)
    for match in itr:
        pos.append(match.span())
    
    answ = {}
    
    for i, v in enumerate(pos):
        if i == len(pos) - 1:
            answ[in_str[v[1]-2]] = in_str[v[1]:]
        else:
            answ[in_str[v[1]-2]] = in_str[v[1]:pos[i+1][0]]
    
    return answ

def get_data_value(answ, v):
    """Return data by value from dictionary."""
    try:
        return answ[v]
    except KeyError:
        return None

# Page renders

def home(request):
    """Render home page."""
    
    content_msg = u'TODO: home content'
    
    if request.user.is_authenticated():
        return render_to_response('app/base_home.html', { 'auth_user': request.user, 'content': content_msg })
    else:
        return render_to_response('app/base_home.html', { 'content': content_msg })

def notes(request):
    """Render notes page."""
    
    if request.user.is_authenticated():
        if request.method == 'POST':
            # add category
            if 'add_cat_title' in request.POST:
                form = AddCategoryForm(request.POST,)
                
                if form.is_valid():
                    cat_title = form.cleaned_data['add_cat_title']
                    cat_parent = form.cleaned_data['add_cat_parent']
                    
                    id = int(cat_parent[4:])
                    
                    add_category(cat_title, id, request.user)
            # delete category
            elif 'del_cat_id' in request.POST:
                form = DeleteCategoryForm(request.POST)
                
                if form.is_valid():
                    cat_id = form.cleaned_data['del_cat_id']
                    
                    id = int(cat_id[4:])
                    
                    delete_category(id)
            # edit category title
            elif 'edt_cat_title' in request.POST:
                form = EditCategoryForm(request.POST)
                
                if form.is_valid():
                    cat_title = form.cleaned_data['edt_cat_title']
                    cat_id = form.cleaned_data['edt_cat_id']
                    
                    id = int(cat_id[4:])
                    
                    category = Category.objects.get(id=id)
                    category.title = cat_title
                    category.save()
            # edit note title
            elif 'edt_note_title' in request.POST:
                form = EditNoteTitleForm(request.POST)
                
                if form.is_valid():
                    note_title = form.cleaned_data['edt_note_title']
                    note_id = form.cleaned_data['edt_note_id']
                    
                    id = int(note_id[5:])
                    
                    note = Entity.objects.get(id=id)
                    note.title = note_title
                    note.save()
            # edit note importance
            elif 'edt_note_importance' in request.POST:
                form = EditNoteImportanceForm(request.POST)
                
                if form.is_valid():
                    note_id = form.cleaned_data['edt_note_importance']
                    
                    id = int(note_id[5:])
                    
                    note = Entity.objects.get(id=id)
                    note.important = not note.important
                    note.save()
            # edit note priority
            elif 'edt_note_priority' in request.POST:
                form = EditNotePriorityForm(request.POST)
                
                if form.is_valid():
                    note_priority = form.cleaned_data['edt_note_priority']
                    note_id = form.cleaned_data['edt_note_id']
                    
                    id = int(note_id[5:])
                    
                    note = Entity.objects.get(id=id)
                    note.priority = note_priority
                    note.save()
            # edit note description
            elif 'edt_note_description' in request.POST:
                form = EditNoteDescriptionForm(request.POST)
                
                if form.is_valid():
                    note_description = form.cleaned_data['edt_note_description']
                    note_id = form.cleaned_data['edt_note_id']
                    
                    id = int(note_id[5:])
                    
                    note = Entity.objects.get(id=id)
                    note.description = note_description
                    note.save()
            # edit note type
            elif 'edt_note_type' in request.POST:
                form = EditNoteTypeForm(request.POST)
                
                if form.is_valid():
                    note_type = form.cleaned_data['edt_note_type']
                    note_id = form.cleaned_data['edt_note_id']
                    
                    id = int(note_id[5:])
                    
                    note = Entity.objects.get(id=id)
                    note.type = note_type
                    note.save()
            # archive note
            elif 'arh_note_id' in request.POST:
                form = ArchiveNoteForm(request.POST)
                
                if form.is_valid():
                    note_id = form.cleaned_data['arh_note_id']
                    
                    id = int(note_id[5:])
                    
                    note = Entity.objects.get(id=id)
                    note.state = "ARH"
                    note.save()
            # delete note
            elif 'del_note_id' in request.POST:
                form = DeleteNoteForm(request.POST)
                
                if form.is_valid():
                    note_id = form.cleaned_data['del_note_id']
                    
                    id = int(note_id[5:])
                    
                    note = Entity.objects.get(id=id)
                    note.delete()
            # restore note
            elif 'res_note_id' in request.POST:
                form = RestoreNoteForm(request.POST)
                
                if form.is_valid():
                    note_id = form.cleaned_data['res_note_id']
                    
                    id = int(note_id[5:])
                    
                    note = Entity.objects.get(id=id)
                    note.state = "ACV"
                    note.save()
            # add data with short form
            elif 'add_shr_input' in request.POST:
                form = AddDataShortForm(request.POST)
                
                if form.is_valid():
                    input = form.cleaned_data['add_shr_input']
                    note_category = form.cleaned_data['add_note_category']
                    
                    cat_id = int(note_category[4:])
                    category = Category.objects.get(id=cat_id)
                    
                    results = parse_input(input)
                    
                    tmp = get_data_value(results, 'n')
                    if tmp != None:
                        type = 'N'
                    else:
                        tmp = get_data_value(results, 't')
                        if tmp != None:
                            type = 'T'
                        else:
                            tmp = get_data_value(results, 'e')
                            if tmp != None:
                                type = 'E'
                    
                    title = tmp
                    
                    description = get_data_value(results, 'c')
                    state = 'ACV'
                    
                    if get_data_value(results, 'i') != None:
                        important = True
                    else:
                        important = False
                    
                    tmp = get_data_value(results, 'p')
                    if tmp != None:
                        if tmp == 'Hot':
                            priority = 'HT'
                        elif tmp == 'Warm':
                            priority = 'WM'
                        elif tmp == 'Middle':
                            priority = 'MD'
                        elif tmp == 'Chilly':
                            priority = 'CH'
                        elif tmp == 'Cold':
                            priority = 'CL'
                    else:
                        priority = 'MD'
                    
                    tmp = get_data_value(results, 'x')
                    if tmp != None:
                        if tmp == 'Complex':
                            complexity = 'C'
                        elif tmp == 'Normal':
                            complexity = 'N'
                        elif tmp == 'Easy':
                            complexity = 'E'
                    else:
                        complexity = None
                    
                    # from_date = get_data_value['']
                    # to_date = get_data_value['']
                    # repeater = get_data_value['r']
                    # reminder = get_data_value['m']
                    
                    data = Entity(user=request.user,
                                  category=category,
                                  type=type,
                                  title=title,
                                  description=description,
                                  state=state,
                                  important=important,
                                  priority=priority,
                                  complexity=complexity)
                    data.save()
            # add data with long form
            elif 'add_note_title' in request.POST:
                form = AddNoteForm(request.POST)
                
                if form.is_valid():
                    note_title = form.cleaned_data['add_note_title']
                    note_description = form.cleaned_data['add_note_description']
                    note_importance = form.cleaned_data['add_note_importance']
                    note_priority = form.cleaned_data['add_note_priority']
                    note_category = form.cleaned_data['add_note_category']
                    
                    cat_id = int(note_category[4:])
                    category = Category.objects.get(id=cat_id)
                    
                    note = Entity(user=request.user,
                                  category=category,
                                  type="N",
                                  title=note_title,
                                  description=note_description,
                                  state="ACV",
                                  important=note_importance,
                                  priority=note_priority)
                    note.save()
            
            return HttpResponsePermanentRedirect(reverse('url-notes'))
        else:
            categories = get_categories(request.user)
            add_cat_form = AddCategoryForm()
            del_cat_form = DeleteCategoryForm()
            edt_cat_form = EditCategoryForm()
            active_notes = get_notes(request.user, 'ACV')
            archived_notes = get_notes(request.user, 'ARH')
            edt_note_title_form = EditNoteTitleForm()
            edt_note_importance_form = EditNoteImportanceForm()
            edt_note_priority_form = EditNotePriorityForm()
            edt_note_description_form = EditNoteDescriptionForm()
            edt_note_type_form = EditNoteTypeForm()
            arh_note_form = ArchiveNoteForm()
            del_note_form = DeleteNoteForm()
            add_note_form = AddNoteForm()
            res_note_form = RestoreNoteForm()
            add_data_short = AddDataShortForm()
            filter_data_short = FilterDataShortForm()
            
            return render_to_response('app/app_notes.html',
                { 'auth_user': request.user,
                  'categories': categories,
                  'add_cat_form': add_cat_form,
                  'del_cat_form': del_cat_form,
                  'edt_cat_form': edt_cat_form,
                  'active_notes': active_notes,
                  'archived_notes': archived_notes,
                  'edt_note_title_form': edt_note_title_form,
                  'edt_note_importance_form': edt_note_importance_form,
                  'edt_note_priority_form': edt_note_priority_form,
                  'edt_note_description_form': edt_note_description_form,
                  'edt_note_type_form': edt_note_type_form,
                  'arh_note_form': arh_note_form,
                  'del_note_form': del_note_form,
                  'add_note_form': add_note_form,
                  'res_note_form': res_note_form,
                  'add_data_short': add_data_short,
                  'filter_data_short': filter_data_short })
    else:
        return HttpResponsePermanentRedirect(reverse('url-home'))
